#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <net/if.h>  
#include <sys/ioctl.h>  
#include <sys/socket.h>  
#include <linux/can.h>  
#include <linux/can/raw.h>  
#include <signal.h>  
#include <time.h>  
#include <errno.h>  

#define CAN_INTERFACE "can0"  
#define TIMER_INTERVAL 1  // 定时器间隔，单位为秒  

void timer_handler(int signum) 
{  
    static int counter = 0;  
    struct sockaddr_can addr;  
    struct ifreq ifr;  
    struct can_frame frame;  
    int sock;  

    // 打开 SocketCAN 套接字  
    if ((sock = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {  
        perror("Socket");  
        exit(1);  
    }  

    strcpy(ifr.ifr_name, CAN_INTERFACE);  
    ioctl(sock, SIOCGIFINDEX, &ifr);  

    addr.can_family = AF_CAN;  
    addr.can_ifindex = ifr.ifr_ifindex;  

    // 绑定套接字到 CAN 接口  
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {  
        perror("Bind");  
        close(sock);  
        exit(1);  
    }  

    // 准备 CAN 帧  
    frame.can_id = 0x123;  // CAN 标识符，可以根据需要修改  
    frame.can_dlc = 1;     // 数据长度码  

    switch (counter % 3) {  
        case 0:  
            frame.data[0] = 1;  
            break;  
        case 1:  
            frame.data[0] = 2;  
            break;  
        case 2:  
            frame.data[0] = 3;  
            break;  
    }  

    // 发送 CAN 帧  
    if (write(sock, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {  
        perror("Write");  
    } else {  
        printf("Sent: %d\n", frame.data[0]);  
    }  

    close(sock);  
    counter++;  
}  

int main() 
{  
    struct sigaction sa;  
    struct sigevent sev;  
    timer_t timerid;  
    struct itimerspec its;  

    // 设置定时器处理函数  
    memset(&sa, 0, sizeof(sa));  
    sa.sa_flags = SA_SIGINFO;  
    sa.sa_sigaction = timer_handler;  
    sigaction(SIGRTMIN, &sa, NULL);  

    // 创建定时器  
    memset(&sev, 0, sizeof(sev));  
    sev.sigev_notify = SIGEV_SIGNAL;  
    sev.sigev_signo = SIGRTMIN;  
    sev.sigev_value.sival_ptr = &timerid;  
    timer_create(CLOCK_REALTIME, &sev, &timerid);  

    // 设置定时器时间  
    its.it_value.tv_sec = TIMER_INTERVAL;  
    its.it_value.tv_nsec = 0;  
    its.it_interval.tv_sec = TIMER_INTERVAL;  
    its.it_interval.tv_nsec = 0;  
    timer_settime(timerid, 0, &its, NULL);  

    // 主循环，保持程序运行  
    while (1) {  
        pause();  // 等待信号  
    }  

    return 0;  
}

// 编译命令：gcc -o can_timer can_timer.c -lpthread